"""
System Management API Router
系统管理API路由 - 系统监控、统计、用户管理
"""

import uuid
from typing import Optional, List, Dict, Any
from datetime import datetime, timedelta

from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, and_, or_, func, desc, text

from ..core.database import get_db
from ..core.logging import error_logger
from ..core.exceptions import ValidationError, PermissionDeniedError
from ..models.user import User
from ..models.system_log import SystemLog, LogLevel, LogCategory
from ..models.generated_content import GeneratedContent, ContentStatus
from ..models.creation_request import CreationRequest
from ..models.task_queue import TaskQueue, TaskStatus
from ..models.folder import Folder
from ..models.content_tag import ContentTag
from ..services.system_monitoring_service import SystemMonitoringService
from ..services.user_service import UserService
from .auth import get_current_user

router = APIRouter()


def require_admin(current_user: User = Depends(get_current_user)) -> User:
    """管理员权限验证依赖"""
    if not current_user.is_admin:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="需要管理员权限"
        )
    return current_user


@router.get("/stats")
async def get_system_stats(
    current_user: User = Depends(require_admin),
    db: AsyncSession = Depends(get_db),
):
    """获取系统统计信息"""
    try:
        monitoring_service = SystemMonitoringService(db)
        
        # 获取系统统计
        stats = await monitoring_service.get_system_statistics()
        
        return {
            "success": True,
            "data": stats
        }
        
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "get_system_stats",
                "user_id": str(current_user.id)
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取系统统计失败，请稍后重试"
        )


@router.get("/health")
async def get_system_health(
    current_user: User = Depends(require_admin),
    db: AsyncSession = Depends(get_db),
):
    """获取系统健康状态"""
    try:
        monitoring_service = SystemMonitoringService(db)
        
        # 获取系统健康状态
        health_status = await monitoring_service.get_system_health()
        
        return {
            "success": True,
            "data": health_status
        }
        
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "get_system_health",
                "user_id": str(current_user.id)
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取系统健康状态失败，请稍后重试"
        )


@router.get("/logs")
async def get_system_logs(
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(50, ge=1, le=200, description="每页数量"),
    level: Optional[str] = Query(None, description="日志级别筛选"),
    category: Optional[str] = Query(None, description="日志分类筛选"),
    user_id: Optional[str] = Query(None, description="用户ID筛选"),
    search: Optional[str] = Query(None, description="搜索关键词"),
    start_date: Optional[str] = Query(None, description="开始日期 (YYYY-MM-DD)"),
    end_date: Optional[str] = Query(None, description="结束日期 (YYYY-MM-DD)"),
    current_user: User = Depends(require_admin),
    db: AsyncSession = Depends(get_db),
):
    """获取系统日志"""
    try:
        # 构建查询条件
        filters = []
        
        if level:
            filters.append(SystemLog.level == level)
        if category:
            filters.append(SystemLog.category == category)
        if user_id:
            filters.append(SystemLog.user_id == uuid.UUID(user_id))
        if search:
            filters.append(
                or_(
                    SystemLog.message.contains(search),
                    SystemLog.details.contains(search)
                )
            )
        if start_date:
            start_datetime = datetime.strptime(start_date, "%Y-%m-%d")
            filters.append(SystemLog.created_at >= start_datetime)
        if end_date:
            end_datetime = datetime.strptime(end_date, "%Y-%m-%d") + timedelta(days=1)
            filters.append(SystemLog.created_at < end_datetime)
        
        # 获取日志列表
        query = select(SystemLog).where(and_(*filters)).order_by(desc(SystemLog.created_at))
        
        # 分页查询
        total_result = await db.execute(select(func.count(SystemLog.id)).where(and_(*filters)))
        total = total_result.scalar()
        
        offset = (page - 1) * page_size
        log_result = await db.execute(query.offset(offset).limit(page_size))
        logs = log_result.scalars().all()
        
        # 格式化日志数据
        items = []
        for log in logs:
            items.append({
                "id": str(log.id),
                "level": log.level,
                "category": log.category,
                "message": log.message,
                "details": log.details or {},
                "user_id": str(log.user_id) if log.user_id else None,
                "ip_address": log.ip_address,
                "user_agent": log.user_agent,
                "created_at": log.created_at.isoformat(),
            })
        
        total_pages = (total + page_size - 1) // page_size
        
        return {
            "success": True,
            "data": {
                "items": items,
                "total": total,
                "page": page,
                "page_size": page_size,
                "total_pages": total_pages,
                "has_next": page < total_pages,
                "has_prev": page > 1,
            }
        }
        
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "get_system_logs",
                "user_id": str(current_user.id),
                "filters": locals().get("filters", [])
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取系统日志失败，请稍后重试"
        )


@router.get("/users")
async def get_user_management(
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(20, ge=1, le=100, description="每页数量"),
    role: Optional[str] = Query(None, description="角色筛选"),
    status: Optional[str] = Query(None, description="状态筛选"),
    search: Optional[str] = Query(None, description="搜索关键词"),
    current_user: User = Depends(require_admin),
    db: AsyncSession = Depends(get_db),
):
    """用户管理 - 获取用户列表"""
    try:
        user_service = UserService(db)
        
        # 构建查询条件
        filters = {}
        if role:
            filters["role"] = role
        if status:
            filters["status"] = status
        if search:
            filters["search"] = search
        
        # 获取用户列表
        result = await user_service.list_users(
            page=page,
            page_size=page_size,
            filters=filters
        )
        
        # 格式化用户数据
        items = []
        for user in result["items"]:
            items.append({
                "id": str(user.id),
                "username": user.username,
                "email": user.email,
                "full_name": user.full_name,
                "role": user.role,
                "status": user.status,
                "avatar_url": user.avatar_url,
                "daily_generation_limit": user.daily_generation_limit,
                "storage_quota_mb": user.storage_quota_mb,
                "used_storage_mb": user.used_storage_mb,
                "email_verified": user.email_verified,
                "two_factor_enabled": user.two_factor_enabled,
                "created_at": user.created_at.isoformat(),
                "last_login_at": user.last_login_at.isoformat() if user.last_login_at else None,
            })
        
        return {
            "success": True,
            "data": {
                "items": items,
                "total": result["total"],
                "page": page,
                "page_size": page_size,
                "total_pages": result["total_pages"],
                "has_next": result["has_next"],
                "has_prev": result["has_prev"],
            }
        }
        
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "get_user_management",
                "user_id": str(current_user.id),
                "filters": locals().get("filters", {})
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取用户列表失败，请稍后重试"
        )


@router.put("/users/{user_id}/role")
async def update_user_role(
    user_id: str,
    role: str = Query(..., description="新角色: user, admin"),
    current_user: User = Depends(require_admin),
    db: AsyncSession = Depends(get_db),
):
    """更新用户角色"""
    try:
        user_service = UserService(db)
        
        # 更新用户角色
        success = await user_service.update_user_role(
            uuid.UUID(user_id),
            role,
            updated_by=current_user
        )
        
        if not success:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="用户不存在或更新失败"
            )
        
        return {
            "success": True,
            "message": "用户角色更新成功"
        }
        
    except HTTPException:
        raise
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "update_user_role",
                "target_user_id": user_id,
                "admin_user_id": str(current_user.id),
                "new_role": role
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="更新用户角色失败，请稍后重试"
        )


@router.put("/users/{user_id}/status")
async def update_user_status(
    user_id: str,
    status: str = Query(..., description="新状态: active, locked, banned"),
    reason: Optional[str] = Query(None, description="状态变更原因"),
    current_user: User = Depends(require_admin),
    db: AsyncSession = Depends(get_db),
):
    """更新用户状态"""
    try:
        user_service = UserService(db)
        
        # 更新用户状态
        success = await user_service.update_user_status(
            uuid.UUID(user_id),
            status,
            reason=reason,
            updated_by=current_user
        )
        
        if not success:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="用户不存在或更新失败"
            )
        
        return {
            "success": True,
            "message": "用户状态更新成功"
        }
        
    except HTTPException:
        raise
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "update_user_status",
                "target_user_id": user_id,
                "admin_user_id": str(current_user.id),
                "new_status": status,
                "reason": reason
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="更新用户状态失败，请稍后重试"
        )


@router.put("/users/{user_id}/limits")
async def update_user_limits(
    user_id: str,
    daily_generation_limit: Optional[int] = Query(None, ge=0, description="每日生成限制"),
    storage_quota_mb: Optional[int] = Query(None, ge=0, description="存储配额(MB)"),
    current_user: User = Depends(require_admin),
    db: AsyncSession = Depends(get_db),
):
    """更新用户限制"""
    try:
        user_service = UserService(db)
        
        # 准备更新数据
        update_data = {}
        if daily_generation_limit is not None:
            update_data["daily_generation_limit"] = daily_generation_limit
        if storage_quota_mb is not None:
            update_data["storage_quota_mb"] = storage_quota_mb
        
        # 更新用户限制
        success = await user_service.update_user_limits(
            uuid.UUID(user_id),
            update_data,
            updated_by=current_user
        )
        
        if not success:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="用户不存在或更新失败"
            )
        
        return {
            "success": True,
            "message": "用户限制更新成功"
        }
        
    except HTTPException:
        raise
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "update_user_limits",
                "target_user_id": user_id,
                "admin_user_id": str(current_user.id),
                "update_data": update_data
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="更新用户限制失败，请稍后重试"
        )


@router.get("/content/stats")
async def get_content_statistics(
    start_date: Optional[str] = Query(None, description="开始日期 (YYYY-MM-DD)"),
    end_date: Optional[str] = Query(None, description="结束日期 (YYYY-MM-DD)"),
    current_user: User = Depends(require_admin),
    db: AsyncSession = Depends(get_db),
):
    """获取内容统计信息"""
    try:
        # 构建日期范围条件
        date_filters = []
        if start_date:
            start_datetime = datetime.strptime(start_date, "%Y-%m-%d")
            date_filters.append(GeneratedContent.created_at >= start_datetime)
        if end_date:
            end_datetime = datetime.strptime(end_date, "%Y-%m-%d") + timedelta(days=1)
            date_filters.append(GeneratedContent.created_at < end_datetime)
        
        # 内容类型统计
        content_type_stats = await db.execute(
            select(
                GeneratedContent.content_type,
                func.count(GeneratedContent.id).label('count'),
                func.sum(GeneratedContent.file_size_bytes).label('total_size')
            ).where(and_(*date_filters))
            .group_by(GeneratedContent.content_type)
        )
        type_stats = content_type_stats.all()
        
        # 状态统计
        status_stats = await db.execute(
            select(
                GeneratedContent.status,
                func.count(GeneratedContent.id).label('count')
            ).where(and_(*date_filters))
            .group_by(GeneratedContent.status)
        )
        status_data = status_stats.all()
        
        # AI提供商统计
        provider_stats = await db.execute(
            select(
                GeneratedContent.ai_provider,
                func.count(GeneratedContent.id).label('count')
            ).where(and_(*date_filters))
            .group_by(GeneratedContent.ai_provider)
        )
        provider_data = provider_stats.all()
        
        # 每日生成趋势
        daily_stats = await db.execute(
            select(
                func.date(GeneratedContent.created_at).label('date'),
                func.count(GeneratedContent.id).label('count')
            ).where(and_(*date_filters))
            .group_by(func.date(GeneratedContent.created_at))
            .order_by(func.date(GeneratedContent.created_at))
        )
        daily_data = daily_stats.all()
        
        return {
            "success": True,
            "data": {
                "content_type_stats": [
                    {
                        "content_type": content_type,
                        "count": count,
                        "total_size_mb": round((total_size or 0) / (1024 * 1024), 2)
                    }
                    for content_type, count, total_size in type_stats
                ],
                "status_stats": [
                    {"status": status, "count": count}
                    for status, count in status_data
                ],
                "provider_stats": [
                    {"provider": provider, "count": count}
                    for provider, count in provider_data
                ],
                "daily_trend": [
                    {
                        "date": date.isoformat(),
                        "count": count
                    }
                    for date, count in daily_data
                ],
                "total_content": sum(count for _, count, _ in type_stats),
                "total_size_mb": round(sum((total_size or 0) for _, _, total_size in type_stats) / (1024 * 1024), 2)
            }
        }
        
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "get_content_statistics",
                "user_id": str(current_user.id),
                "date_range": f"{start_date} to {end_date}"
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取内容统计失败，请稍后重试"
        )


@router.get("/tasks/stats")
async def get_task_statistics(
    current_user: User = Depends(require_admin),
    db: AsyncSession = Depends(get_db),
):
    """获取任务队列统计"""
    try:
        # 任务状态统计
        task_stats = await db.execute(
            select(
                TaskQueue.status,
                func.count(TaskQueue.id).label('count')
            ).group_by(TaskQueue.status)
        )
        status_stats = task_stats.all()
        
        # 平均处理时间
        avg_processing_time = await db.execute(
            select(
                func.avg(TaskQueue.processing_time).label('avg_time')
            ).where(
                and_(
                    TaskQueue.status == TaskStatus.COMPLETED,
                    TaskQueue.processing_time.isnot(None)
                )
            )
        )
        avg_time = avg_processing_time.scalar()
        
        # 等待时间最长的任务
        oldest_pending = await db.execute(
            select(TaskQueue).where(
                TaskQueue.status == TaskStatus.PENDING
            ).order_by(TaskQueue.created_at).limit(5)
        )
        oldest_tasks = oldest_pending.scalars().all()
        
        return {
            "success": True,
            "data": {
                "task_status_stats": [
                    {"status": str(status), "count": count}
                    for status, count in status_stats
                ],
                "avg_processing_time_seconds": round(float(avg_time or 0), 2),
                "total_tasks": sum(count for _, count in status_stats),
                "pending_tasks": next((count for status, count in status_stats if status == TaskStatus.PENDING), 0),
                "processing_tasks": next((count for status, count in status_stats if status == TaskStatus.PROCESSING), 0),
                "oldest_pending_tasks": [
                    {
                        "task_id": str(task.id),
                        "task_type": task.task_type,
                        "priority": task.priority,
                        "created_at": task.created_at.isoformat(),
                        "wait_time_minutes": round((datetime.utcnow() - task.created_at).total_seconds() / 60, 1)
                    }
                    for task in oldest_tasks
                ]
            }
        }
        
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "get_task_statistics",
                "user_id": str(current_user.id)
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取任务统计失败，请稍后重试"
        )


@router.post("/logs/clear")
async def clear_system_logs(
    days_to_keep: int = Query(30, ge=1, le=365, description="保留天数"),
    current_user: User = Depends(require_admin),
    db: AsyncSession = Depends(get_db),
):
    """清理系统日志"""
    try:
        monitoring_service = SystemMonitoringService(db)
        
        # 清理旧日志
        deleted_count = await monitoring_service.clear_old_logs(days_to_keep=days_to_keep)
        
        return {
            "success": True,
            "data": {
                "deleted_count": deleted_count,
                "days_to_keep": days_to_keep
            },
            "message": f"成功清理 {deleted_count} 条日志记录"
        }
        
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "clear_system_logs",
                "admin_user_id": str(current_user.id),
                "days_to_keep": days_to_keep
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="清理系统日志失败，请稍后重试"
        )


@router.post("/maintenance/vacuum")
async def vacuum_database(
    current_user: User = Depends(require_admin),
    db: AsyncSession = Depends(get_db),
):
    """数据库维护 - VACUUM操作"""
    try:
        # 执行VACUUM操作
        await db.execute(text("VACUUM"))
        
        return {
            "success": True,
            "message": "数据库VACUUM操作完成"
        }
        
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "vacuum_database",
                "admin_user_id": str(current_user.id)
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="数据库维护失败，请稍后重试"
        )


# 导出路由
__all__ = ["router", "require_admin"]